import tensorflow as tf
import numpy as np


def sep(label=''):
    print('-' * 32, label, '-' * 32, sep='')


# 1.	以上给予的的背景小知识的了解，请使用TensorFlow完成以下相关的题目要求。
# (1)	以下为一个判断逻异或的的数据，按照要求去做逻辑回归运算；
# ①	正确加载下图给予的亦或初始化数据（7分）
x_data = [[1, 2],
      [2, 3],
      [3, 1],
      [4, 3],
      [5, 3],
      [6, 2]]
y_data = [[0],
      [0],
      [0],
      [1],
      [1],
      [1]]
x_data = np.array(x_data)
m, n = x_data.shape
y_data = np.array(y_data)

# ②	合理的运用tf.placeholder进行定义（7分）
x = tf.compat.v1.placeholder(tf.float32, [None, n], 'ph_x')
y = tf.compat.v1.placeholder(tf.float32, [None, 1], 'ph_y')

# ③	合理的根据以上数据进行偏执和权重的设置，注意维度问题。（7分）
w = tf.Variable(tf.random.normal([n, 1]), dtype=tf.float32, name='w')
b = tf.Variable(tf.random.normal([1]), dtype=tf.float32, name='b')

# ④	调用tf.sigmoid模块完成预测模型（7分）
h = tf.sigmoid(tf.matmul(x, w) + b)

# ⑤	用底层写出损失函数，注意是交叉熵分类。（7分）
cost = tf.math.negative(tf.reduce_mean(
    y * tf.math.log(h) + (1 - y) * tf.math.log(1 - h)
    , axis=0
))

# ⑥	定义梯度下降（可以选择优化器种类也行）（7分）
train = tf.compat.v1.train.GradientDescentOptimizer(learning_rate=0.01)\
    .minimize(cost)

# ⑦	创建会话，进行运算计算图分析。（7分）
with tf.compat.v1.Session() as sess:
    with tf.compat.v1.summary.FileWriter('log/logi_regr_again', sess.graph) as fw:
        pass
    sess.run(tf.compat.v1.global_variables_initializer())

    # ⑧	进行迭代运算，要求1000次
    iters = 1000
    group = iters // 10
    for i in range(iters):
        wv, bv, hv, costv, _ = sess.run([w, b, h, cost, train],
                 feed_dict={x: x_data, y: y_data})
        # ⑨	合理的步数（可以是40步）给出损失值结果。（7分）
        if i % group == 0:
            print(f'#{i + 1} cost = {costv}, w.T = {np.transpose(wv)}, b = {bv}')
    if i % group != 0:
        print(f'#{i + 1} cost = {costv}, w.T = {np.transpose(wv)}, b = {bv}')

    # ⑩	最后进入验证预测功能，要求加入正确的的注释（7分）
    x_test = [[1, 1], [10, 1], [10, 10]]
    h_test = sess.run(h > 0.5, feed_dict={x: x_test})
    print(x_test)
    print(h_test)
